/**
 * @file   FEMSpace.h
 * @author HirasawaYui <yui@Ubuntu18-04>
 * @date   Mon Oct 26 23:20:09 2020
 * 
 * @brief  A space for generating and storing some components of FEM.
 *         2D possion equation 
 * 
 */
#ifndef _FEMSPACE_H_
#define _FEMSPACE_H_
#include "Element.h"
#include <map>

/// Use std::vector<std::map<int,double> > to store stiff matrix, idea by LSJ
typedef std::vector<std::map<int, double> > StiffMat;
class FEMSpace

{
private:
    /// The element of the FEMSpace;
    Element _BaseEle;
    /// The count of dofs in each row;
    int _SdLen;
    /// The number of nodes in this FEMSpace; 
    int _DIM;
    /// The total count of elements;
    int _NEle;
    /// store the right hands term of this FEMSpace;
    std::vector<double> _rhs;
    /// the mark whether this node is boundary
    std::vector<int> _BndMark;
    /// function pointer to f term;
    double(*_func) (double, double);
    /// the real solution
    double (*_RealSltn) (double, double);

public:
    /// StiffMat of this FEMSpace;
    StiffMat _A;
public:
    FEMSpace(){
    };
    /**
     * @brief Construct a new FEMSpace object
     * 
     * @param SdLen 
     * @param func 
     */
    FEMSpace(int SdLen, double(*func)(double, double),double (*u)(double,double));
    /**
     * @brief Construct a new FEMSpace object
     * 
     * @param SdLen vgdb
     */
    FEMSpace(int SdLen);
    /** 
     * @brief Output the global indexes of all dofs in ith element, in order.
     * 
     * @param i  
     * 
     * @return 
     */
    std::vector<int> NodeofEle(int i);
    /**
     * @brief Generate the stiff Matrix A;
     * 
     */
    void GenerateA();
    /**
     * @brief Print the stiff Matrix A;
     * 
     */
    void PrintA();
    /**
     * @brief Generate the right hands term;
     * 
     */
    void GenerateRhs();
    /**
     * @brief Print the right hands term;
     * 
     */
    void PrintRhs();
    /**
     * @brief Deal with the Boundary condition;
     * 
     */
    void DealBoundary();
    /**
     * @brief Reset the sdlen; 
     * 
     * @param SdLen 
     */
    void Set_SdLen(int SdLen);
    /** 
     * @brief Return stiff matrix A
     * 
     * 
     * @return 
     */
    StiffMat A();
    /**
     * @brief Return rhs;
     * 
     * @return std::vector<double> 
     */
    std::vector<double> Rhs();
};
#else
#endif
